package com.hyq.learn.api.util;

import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;

/**
 * @author heyuqin
 * @date 2024/5/13 17:56
 */
public class VideoUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(VideoUtil.class);
    // 视频截取时长
    private static final Integer DURATION = 3;

    public static byte[] generatePreviewVideo(byte[] source, String targetPath) {
        try (FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(new ByteArrayInputStream(source));
             FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(targetPath, grabber.getImageWidth(), grabber.getImageHeight(), grabber.getAudioChannels())) {
            grabber.start();
            // 重新设置 宽高
            recorder.setImageWidth(grabber.getImageWidth());
            recorder.setImageHeight(grabber.getImageHeight());
            // 设置视频编码层格式
            recorder.setVideoCodec(grabber.getVideoCodec());
            // 设置视频格式
            recorder.setFormat(grabber.getFormat());
            // 设置每秒多少帧
            recorder.setFrameRate(grabber.getFrameRate());
            // 设置关键帧
            recorder.setGopSize(3);
            recorder.setAudioChannels(grabber.getAudioChannels());
            recorder.setVideoBitrate(grabber.getVideoBitrate());
            recorder.start();

            Frame inFrame;
            while ((inFrame = grabber.grab()) != null) {
                if (inFrame.timestamp > DURATION * 1000 * 1000){
                    break;
                }
                recorder.record(inFrame);
            }
            recorder.flush();
        } catch (Exception e) {
            LOGGER.error("preview video capture failed,filePath:{},errorMsg:{}",targetPath, e.getMessage());
        }
        // 生成成功
        File file = new File(targetPath);
        try (FileInputStream fileInputStream = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream()){
            byte[] bytes = new byte[1024];
            int len = 0;
            while (-1 != (len = fileInputStream.read(bytes))) {
                bos.write(bytes, 0, len);
            }
            byte[] result = bos.toByteArray();
            return result;
        }catch (Exception e) {
            LOGGER.error("preview video capture failed,filePath:{},errorMsg:{}",targetPath, e.getMessage());
            return null;
        }finally {
            file.deleteOnExit();
        }
    }
}
